package com.zrf.gulimall.ware.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zrf.gulimall.commnon.core.enums.PurchaseDetailStatusEnum;
import com.zrf.gulimall.commnon.core.enums.PurchaseStatusEnum;
import com.zrf.gulimall.commnon.core.exception.CustomException;
import com.zrf.gulimall.common.database.utils.PageUtils;
import com.zrf.gulimall.common.database.utils.Query;
import com.zrf.gulimall.ware.dao.PurchaseDao;
import com.zrf.gulimall.ware.entity.PurchaseDetailEntity;
import com.zrf.gulimall.ware.entity.PurchaseEntity;
import com.zrf.gulimall.ware.entity.WareSkuEntity;
import com.zrf.gulimall.ware.service.PurchaseDetailService;
import com.zrf.gulimall.ware.service.PurchaseService;
import com.zrf.gulimall.ware.service.WareSkuService;
import com.zrf.gulimall.ware.vo.MergeVo;
import com.zrf.gulimall.ware.vo.PurchaseFinishVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;


@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {

	@Autowired
	private PurchaseDetailService purchaseDetailService;
	@Autowired
	private WareSkuService wareSkuService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                new QueryWrapper<PurchaseEntity>()
        );

        return new PageUtils(page);
    }

	@Override
	public PageUtils queryPageUnReceive(Map<String, Object> params) {
		IPage<PurchaseEntity> page = this.lambdaQuery()
				.eq(PurchaseEntity::getStatus, 0)
				.or()
				.eq(PurchaseEntity::getStatus, 1)
				.page(new Query<PurchaseEntity>().getPage(params));
		return new PageUtils(page);
	}

	@Override
	public void receive(List<Long> purchaseIdList) {
    	// 查询订单状态，并过滤是否为新建或已分配状态
		List<PurchaseEntity> purchaseEntities = this.listByIds(purchaseIdList);
		List<PurchaseEntity> updateList = purchaseEntities.stream().filter(
				item -> PurchaseStatusEnum.CREATED.getCode() == item.getStatus() || PurchaseStatusEnum.ASSIGNED.getCode() == item.getStatus()
		).peek(item -> {
			item.setStatus(PurchaseStatusEnum.RECEIVE.getCode());
			item.setUpdateTime(new Date());
		}).collect(Collectors.toList());
		if (CollUtil.isNotEmpty(updateList)) {
			this.updateBatchById(updateList);
			// 修改采购需求状态
			List<Long> ids = updateList.stream().map(PurchaseEntity::getId).collect(Collectors.toList());
			List<PurchaseDetailEntity> detailEntities = purchaseDetailService.queryByPurchaseIds(ids);
			List<PurchaseDetailEntity> updateDetails = detailEntities.stream().peek(item -> {
				item.setStatus(PurchaseDetailStatusEnum.BUYING.getCode());
			}).collect(Collectors.toList());
			purchaseDetailService.updateBatchById(updateDetails);
		}
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void mergePurchase(MergeVo mergeVo) {
		if (Objects.isNull(mergeVo.getPurchaseId())) {
			PurchaseEntity purchaseEntity = new PurchaseEntity();
			purchaseEntity.setStatus(PurchaseStatusEnum.CREATED.getCode());
			purchaseEntity.setCreateTime(new Date());
			purchaseEntity.setUpdateTime(new Date());
			this.save(purchaseEntity);
			mergeVo.setPurchaseId(purchaseEntity.getId());
		}
		PurchaseEntity purchaseEntity = this.getById(mergeVo.getPurchaseId());
		if (!purchaseEntity.getStatus().equals(PurchaseStatusEnum.CREATED.getCode()) &&
				!purchaseEntity.getStatus().equals(PurchaseStatusEnum.ASSIGNED.getCode())) {
			throw new CustomException("无法合并！");
		}
		List<PurchaseDetailEntity> purchaseDetailEntities = mergeVo.getItems().stream().map(item -> {
			PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();
			purchaseDetailEntity.setStatus(PurchaseDetailStatusEnum.ASSIGNED.getCode());
			purchaseDetailEntity.setPurchaseId(mergeVo.getPurchaseId());
			purchaseDetailEntity.setId(item);
			return purchaseDetailEntity;
		}).collect(Collectors.toList());
		purchaseDetailService.updateBatchById(purchaseDetailEntities);
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public void done(PurchaseFinishVo purchaseFinishVos) {
    	// 若订单已完成，则不操作
		PurchaseEntity one = this.lambdaQuery()
				.eq(PurchaseEntity::getId, purchaseFinishVos.getId())
				.one();
		if (one.getStatus().equals(PurchaseStatusEnum.FINISH.getCode())) {
			return;
		}
		// 更新订购单，若有订购项失败，则整个订购单状态为有异常
		PurchaseEntity purchaseEntity = new PurchaseEntity();
		purchaseEntity.setId(purchaseFinishVos.getId());
		purchaseEntity.setStatus(PurchaseStatusEnum.FINISH.getCode());
		// 更新采购项
		List<PurchaseDetailEntity> purchaseDetailEntities = purchaseFinishVos.getItems().stream().map(item -> {
			PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();
			purchaseDetailEntity.setId(item.getItemId());
			// 采购项采购失败，采购单状态改为有异常
			if (item.getStatus().equals(PurchaseDetailStatusEnum.HASERROR.getCode())) {
				purchaseEntity.setStatus(PurchaseStatusEnum.HASERROR.getCode());
			}
			purchaseDetailEntity.setStatus(item.getStatus());
			return purchaseDetailEntity;
		}).collect(Collectors.toList());
		purchaseDetailService.updateBatchById(purchaseDetailEntities);
		// 过滤失败的采购项，获取采购项id，查询其商品skuId和仓库wareId和数量
		List<Long> purchaseDetailsIds = purchaseDetailEntities.stream().filter(item -> !item.getStatus().equals(PurchaseDetailStatusEnum.HASERROR.getCode())).map(PurchaseDetailEntity::getId).collect(Collectors.toList());
		List<PurchaseDetailEntity> purchaseDetailEntityList = purchaseDetailService.listByIds(purchaseDetailsIds);
		// 构建库存信息，更新
		List<WareSkuEntity> wareSkuEntities = purchaseDetailEntityList.stream().map(item -> {
			WareSkuEntity wareSkuEntity = new WareSkuEntity();
			wareSkuEntity.setSkuId(item.getSkuId());
			wareSkuEntity.setWareId(item.getWareId());
			wareSkuEntity.setStock(item.getSkuNum());
			return wareSkuEntity;
		}).collect(Collectors.toList());
		wareSkuService.addStockBySkuAndWareId(wareSkuEntities);
		// 更新采购单状态
		purchaseEntity.setUpdateTime(new Date());
		this.updateById(purchaseEntity);
	}

}